home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / Apps / ArchiveUtils / nx_arc / arcusq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-20  |  2.6 KB  |  110 lines

  1. /*
  2.  * $Log:    arcusq.c,v $
  3.  * Revision 1.1  88/04/11  18:45:37  hyc
  4.  * Initial revision
  5.  * 
  6.  * Revision 1.3  87/08/13  17:06:12  hyc
  7.  * Run thru indent, fixed some signed vs. unsigned problems
  8.  * with bp <-> buf, and inbuf and localbuf...
  9.  *  Revision 1.2  87/07/21  09:31:43  hyc *** empty
  10.  * log message ***
  11.  * 
  12.  */
  13.  
  14. /*
  15.  * ARC - Archive utility - ARCUSQ
  16.  * 
  17.  * Version 3.14, created on 07/25/86 at 13:04:19
  18.  * 
  19.  * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  20.  * 
  21.  * By:  Thom Henderson
  22.  * 
  23.  * Description: This file contains the routines used to expand a file which was
  24.  * packed using Huffman squeezing.
  25.  * 
  26.  * Most of this code is taken from an USQ program by Richard Greenlaw, which was
  27.  * adapted to CI-C86 by Robert J. Beilstein.
  28.  * 
  29.  * Language: Computer Innovations Optimizing C86
  30.  */
  31. #include <stdio.h>
  32. #include "arc.h"
  33.  
  34. /* stuff for Huffman unsqueezing */
  35.  
  36. #define ERROR (-1)
  37.  
  38. #define SPEOF 256        /* special endfile token */
  39. #define NUMVALS 257        /* 256 data values plus SPEOF */
  40.  
  41. struct nd {            /* decoding tree */
  42.     INT             child[2];    /* left, right */
  43. }               node[NUMVALS];    /* use large buffer */
  44.  
  45. static INT      bpos;        /* last bit position read */
  46. static INT      curin;        /* last byte value read */
  47. static INT      numnodes;    /* number of nodes in decode tree */
  48.  
  49. static          INT
  50. get_int(f)            /* get an integer */
  51.     FILE           *f;    /* file to get it from */
  52. {
  53.     return (getc_unp(f) | (getc_unp(f) << 8)) & 0xFFFF;
  54. }
  55.  
  56. INT
  57. init_usq(f)            /* initialize Huffman unsqueezing */
  58.     FILE           *f;    /* file containing squeezed data */
  59. {
  60.     INT             i;    /* node index */
  61.  
  62.     bpos = 99;        /* force initial read */
  63.  
  64.     numnodes = get_int(f);
  65.  
  66.     if (numnodes < 0 || numnodes >= NUMVALS)
  67.         arc_abort("File has an invalid decode tree");
  68.  
  69.     /* initialize for possible empty tree (SPEOF only) */
  70.  
  71.     node[0].child[0] = -(SPEOF + 1);
  72.     node[0].child[1] = -(SPEOF + 1);
  73.  
  74.     for (i = 0; i < numnodes; ++i) {    /* get decoding tree from
  75.                          * file */
  76.         node[i].child[0] = get_int(f);
  77.         node[i].child[1] = get_int(f);
  78.     }
  79. }
  80.  
  81. int
  82. getc_usq(f)            /* get byte from squeezed file */
  83.     FILE           *f;    /* file containing squeezed data */
  84. {
  85.     int             i;    /* tree index */
  86.  
  87.     /* follow bit stream in tree to a leaf */
  88.  
  89.     for (i = 0; i >= 0;) {    /* work down(up?) from root */
  90.         if (++bpos > 7) {
  91.             if ((curin = getc_unp(f)) == ERROR)
  92.                 return (ERROR);
  93.             bpos = 0;
  94.  
  95.             /* move a level deeper in tree */
  96.             i = node[i].child[1 & curin];
  97.         } else
  98.             i = node[i].child[1 & (curin >>= 1)];
  99.     }
  100.  
  101.     /* decode fake node index to original data value */
  102.  
  103.     i = -(i + 1);
  104.  
  105.     /* decode special endfile token to normal EOF */
  106.  
  107.     i = (i == SPEOF) ? EOF : i;
  108.     return i;
  109. }
  110.